package com.jamlu.framework.ui.status;

import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.blankj.utilcode.util.ToastUtils;
import com.jamlu.framework.R;
import com.jamlu.framework.utils.ToastPts;

import java.util.ArrayList;

import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;

/**
 * 能对官方的ViewGroup,ListView,RecyclerView,直接变为状态布局，自定义的View不一定行，看对view是怎样处理
 * Created by DMing at 2018/2/13 0013
 */

class StatusView implements IStatus, View.OnClickListener {

    private ProgressBar mPbStatus; //进度条
    private TextView mTxtStatus; //状态信息
    private View sView; //状态布局
    private ArrayList<View> sourceView = new ArrayList<>(); //临时保存View
    private ViewGroup rootView; //需要状态的根布局
    @Status
    private int status; //状态
    private StatusRequest statusRequest; //请求run
    private CompositeDisposable mCompositeDisposable; //disposable池
    private Disposable mDisposable;//取消
    private IStatus subIStatus; //同个布局有两个拥有状态的情况下，第二个状态布局


    StatusView(ViewGroup viewGroup, CompositeDisposable mCompositeDisposable, StatusRequest statusRequest) { //每次都是new出来的，上面静态包裹
        this.rootView = viewGroup;
        this.mCompositeDisposable = mCompositeDisposable;
        this.statusRequest = statusRequest;
        if (viewGroup instanceof RecyclerView){
            RecyclerView mRecyclerView = (RecyclerView) viewGroup;
            mRecyclerView.setLayoutManager(new LinearLayoutManager(viewGroup.getContext()));
            mRecyclerView.setAdapter(new RecyclerView.Adapter() {
                @Override
                public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
                    ensureInitStatusView();
                    return new RecyclerView.ViewHolder(sView) {};
                }

                @Override
                public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

                }

                @Override
                public int getItemCount() {
                    return 1;
                }
            });
        }else if (viewGroup instanceof ListView){
            ListView mListView = (ListView) viewGroup;
            ensureInitStatusView();
            ViewGroup.LayoutParams layoutParams = mListView.getLayoutParams();
            sView.setLayoutParams(new ListView.LayoutParams(layoutParams.width,layoutParams.height));
            mListView.addFooterView(sView);
            mListView.setAdapter(new BaseAdapter() {
                @Override
                public int getCount() {
                    return 0;
                }

                @Override
                public Object getItem(int position) {
                    return null;
                }

                @Override
                public long getItemId(int position) {
                    return 0;
                }

                @Override
                public View getView(int position, View convertView, ViewGroup parent) {
                    return null;
                }
            });
        }else {
            ensureInitStatusView();
            for (int i = 0; i < rootView.getChildCount(); i++) {
                sourceView.add(rootView.getChildAt(i));
            }
            rootView.removeAllViews();
            rootView.addView(sView);
        }
        this.status = LOADING;
        if (statusRequest != null) {
            mDisposable = statusRequest.run(StatusView.this); //这个肯定是新的
            mCompositeDisposable.add(mDisposable);
        }
    }

    private void ensureInitStatusView(){
        sView = LayoutInflater.from(rootView.getContext()).inflate(R.layout.layout_status,rootView,false);
        mPbStatus = sView.findViewById(R.id.pb_wrong_status);
        mTxtStatus = sView.findViewById(R.id.txt_status_msg);
        sView.setOnClickListener(StatusView.this);
    }


    @Override
    public void onClick(View v) {
        request();
    }

    /**
     * 设置第二个状态布局
     * @param iStatus 第二个状态布局
     */
    void setSubIStatus(IStatus iStatus){
        this.subIStatus = iStatus;
    }

    /**
     *
     * @param status 状态
     * @param obj 可选传入参数，可能为空
     */
    @Override
    public void switchStatus(int status, Object... obj) {
        this.status = status;
        switch (status){
            case LOADING:
                if (sView != null){
                    mPbStatus.setVisibility(View.VISIBLE);
                    mTxtStatus.setText(sView.getContext().getString(R.string.status_loading));
                }
                break;
            case SUCCESS:
                if (sView != null){
                    if (rootView instanceof RecyclerView){
                        RecyclerView mRecyclerView = (RecyclerView) rootView;
                        mRecyclerView.setLayoutManager(null);
                        mRecyclerView.setAdapter(null);
                    }else if (rootView instanceof ListView) {
                        ListView mListView = (ListView) rootView;
                        mListView.removeFooterView(sView);
                    }else {
                        rootView.removeAllViews();
                        for (int i = 0; i < sourceView.size(); i++) {
                            rootView.addView(sourceView.get(i));
                        }
                    }
                    if (this.subIStatus != null)this.subIStatus.switchStatus(SUCCESS,obj); //为了传递给第二个状态布局
                    releaseRef(); //成功，移除布局，把所有东西都清空
                }
                break;
            case NOTHING:
                if (sView != null){
                    mPbStatus.setVisibility(View.GONE);
                    mTxtStatus.setText(sView.getContext().getString(R.string.status_nothing_retry));
                }else {
                    ToastUtils.showShort(R.string.status_nothing);
                }
                break;
            case ERROR_RESPOND:
                if (obj != null && obj.length == 1) {
                    String msg = (String) obj[0];
                    if (sView != null) {
                        mPbStatus.setVisibility(View.GONE);
                        mTxtStatus.setText(String.format("%s%s", sView.getContext().getString(R.string.retry), msg));
                    }else {
                        ToastUtils.showShort(msg);
                    }
                }else {
                    if (sView != null) {
                        mPbStatus.setVisibility(View.GONE);
                        mTxtStatus.setText(sView.getContext().getString(R.string.status_error_retry));
                    }else {
                        ToastUtils.showShort(R.string.status_error);
                    }
                }
                break;
            case ERROR_NETWORK:
                if (sView != null) {
                    mPbStatus.setVisibility(View.GONE);
                    mTxtStatus.setText(sView.getContext().getString(R.string.status_error_retry));
                }else {
                    ToastUtils.showShort(R.string.status_error);
                }
                break;
            case NO_NETWORK:
                if (sView != null){
                    mPbStatus.setVisibility(View.GONE);
                    mTxtStatus.setText(sView.getContext().getString(R.string.status_no_net_retry));
                }else {
                    ToastUtils.showShort(R.string.status_no_net);
                }
                break;
            case TOKEN_EXPIRED:
                if (sView != null) {
                    mPbStatus.setVisibility(View.GONE);
                    mTxtStatus.setText(sView.getContext().getString(R.string.status_error_retry));
                }else {
                    ToastPts.show(R.string.status_error_token);
                }
                break;
        }
    }

    @Override
    public @Status int getStatus() {
        return status;
    }

    @Override
    public void request() {
        if (statusRequest != null && status != LOADING){
            switchStatus(LOADING);
            if (mDisposable != null)mCompositeDisposable.remove(mDisposable);
            mDisposable = statusRequest.run(StatusView.this);
            mCompositeDisposable.add(mDisposable);
        }
    }

    /**
     * 手动释放
     */
    @Override
    public void releaseRef() {
//        if (mDisposable != null && mCompositeDisposable != null)mCompositeDisposable.remove(mDisposable);
        sourceView.clear();
        sourceView = null;
        sView = null;
        rootView = null;
        mPbStatus = null;
        mTxtStatus = null;
//        statusRequest = null;
//        mCompositeDisposable = null;
//        mDisposable = null;
        subIStatus = null;
    }
}
